<?php

class Model {

    private $table;
    //声明一个table属性
    private static $link = null;
    private $opt;

    public function __construct($table) {
        $this->table = C('DB_PREFIX') . $table;
        //初始化table表
        $this->_connect();
        //连接数据库
        $this->_opt();
        //初始化opt信息
    }

    private function _opt() {
        $this->opt = array(
            'field' => '*',
            'where' => '',
            'group' => '',
            'having' => '',
            'order' => '',
            'limit' => ''
        );
    }

    //获取单条数据
    public function find() {
        //取得单条数据
        $data = $this->all();
        //将单条数据变成一维数组
        return current($data);
    }

    public function all() {
        //组合select语句
        $sql = 'SELECT ' . $this->opt['field'] . ' FROM ' . $this->table . $this->opt['where'] . $this->opt['group'] . $this->opt['having'] . $this->opt['order'] . $this->opt['limit'];
        //返回query自定义方法所查询到的结果集
        return $this->query($sql);
    }

    public function field($field) {
        //field域opt信息
        $this->opt['field'] = $field;
        //返回当前对象
        return $this;
    }

    public function group($group) {
        //group by域opt信息
        $this->opt['group'] = ' GROUP BY ' . $group;
        //返回当前对象
        return $this;
    }

    public function order($order) {
        //order by域opt信息
        $this->opt['order'] = ' ORDER BY ' . $order;
        //返回当前对象
        return $this;
    }

    public function limit($limit) {
         //LIMIT域opt信息
        $this->opt['limit'] = ' LIMIT ' . $limit;
        //返回当前对象
        return $this;
    }

    public function having($having) {
        //HAVING域opt信息
        $this->opt['having'] = ' HAVING ' . $having;
        //返回当前对象
        return $this;
    }

    public function where($where) {
        //where域opt信息
        $this->opt['where'] = ' WHERE ' . $where;
        //返回当前对象
        return $this;
    }

    public function query($sql) {
        //自定义查询方法
        $result = self::$link->query($sql);
        //开始查询sql，返回结果集
        $this->_error($sql);
        //错误的话，报错并终止
        $rows = array();
        while ($row = $result->fetch_assoc()) {
            $rows[] = $row;
            //取出所有结果，变成结果集，返回出来
        }

        $result->free_result();
        //        释放结果集
        return $rows;
        //        返回结果集
    }

    private function _error($sql) {
        //错误信息
        if (self::$link->errno) {
            echo 'SQL : ' . '<span style="color:red;font-size:20px;">' . $sql . '</span><br/><br/>' . 'Error : ' . self::$link->error;
            die;
        }
    }

    private function _connect() {
        //连接数据库方法
        if (!is_null(self::$link)) {
            return;
        }
        //如果已经连接了，就不需要再连接，直接跳出方法
        $mysqli = @new mysqli(C('DB_HOST'), C('DB_USER'), C('DB_PASSWORD'), C('DB_NAME'));
        //mysqli连接数据库，使用数据库
        if ($mysqli->connect_errno) {
            //如果有错误信息，则返回错误信息，并die
            echo 'Error ' . $mysqli->connect_errno . ': ' . $mysqli->connect_error;
            die;
        }
        $mysqli->query('SET NAMES ' . C('DB_CHARSET'));
        //设置字符集
        self::$link = $mysqli;
        //给静态方法赋值-对象
    }

    public function del() {
        //删除某个元素
        if (empty($this->opt['where'])) {
            die('删除语句必须有where条件！');
        }
        //组合sql
        $sql = 'DELETE FROM ' . $this->table . $this->opt['where'];
        //返回受影响条数
        return $this->exec($sql);
    }

    public function add($data = null) {
        //如果add里面没有参数，就用$_POST,否则用参数
        if (is_null($data)) {
            $data = $_POST;
        }
        //声明两个变量，用来存取键名和键值，并用逗号连接
        $keys = '';
        $values = '';
        foreach ($data as $key => $v) {
            //遍历，对键名键值进行组合
            $keys.=adds_html($key) . ',';
            $values.="'" . adds_html($v) . "'" . ',';
        }
            //去除最右面的逗号
        $keys = rtrim($keys, ',');
        $values = rtrim($values, ',');
            //组合sql
        $sql = 'INSERT INTO ' . $this->table . '(' . $keys . ')' . ' values ' . '(' . $values . ')';
        return $this->exec($sql);
    }

    public function exec($sql) {
        //执行无结果集的增删改的方法
        self::$link->query($sql);
        //传入已组合好的sql语句，执行sql
        $this->_error($sql);
        //如果有错误则显示错误信息
        return self::$link->insert_id ? self::$link->insert_id : self::$link->affected_rows;
        //如果是插入返回插入的id，否则返回受影响条数
    }

    public function update($data = null) {
        //如果data里面没有参数，就用$_POST,否则用参数
        if (is_null($data)) {
            $data = $_POST;
        }
        //申明一个变量，组合键名键值
        $val = '';
        foreach ($data as $key => $v) {
            $val.=$key . '=' . '"' . $v . '"' . ',';
        }
        //去除最右面的逗号
        $val = rtrim($val, ',');
        //只允许一定条件范围的update
        if (empty($this->opt['where'])) {
            die('update语句必须要有where条件！');
        }
        //组合sql语句
        $sql = 'update  ' . $this->table . ' SET ' . $val . $this->opt['where'];
        //执行update
        return $this->exec($sql);
    }

}
